package com.atguigu.daijia.common.loginCheck;

import com.atguigu.daijia.common.constant.RedisConstant;
import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.common.util.AuthContextHolder;
import com.atguigu.daijia.common.util.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * 切面类
 * 所有被@LoginCheck注解标注的类都要进行登陆校验
 */
@Component
@Aspect
@Slf4j
public class LoginCheckAspect {
    @Resource
    private HttpServletRequest request;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Pointcut("@annotation(com.atguigu.daijia.common.loginCheck.LoginCheck)")
    public void pointcut() {

    }

    @Around(value = "pointcut()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        // 1. 获取token
        log.info("切面类执行了-开始进行登陆校验");
        String token = request.getHeader("token");
        // 2. token格式校验
        if (!JwtUtil.verifyJWT(token)) {
            throw new GuiguException(ResultCodeEnum.SIGN_ERROR);
        }
        // 3. 是否存在于redis中
        String userId = stringRedisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
        if (!StringUtils.hasText(userId)) {
            throw new GuiguException(ResultCodeEnum.SIGN_OVERDUE);
        }
        // 4 将customerId放入threadLocal中
        AuthContextHolder.setUserId(Long.valueOf(userId));
        // 5. 放行
        return joinPoint.proceed();
    }
}
